﻿/*
 * Copyright 2012 Rene Prost, Registrite ja Infosüsteemide Keskus 
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 */

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web.Services.Description;
using NUnit.Framework;
using Xtee.Core;

namespace Xtee.CodeDom.Test.Wsdl
{
    [TestFixture]
    public class WsdlGeneratorIntegrationTests
    {
        private DateTime start;

        [SetUp]
        public void Setup()
        {
            start = DateTime.Now;
        }
       
        [Test]
        public void CanGenerateDocumentRepositoryCode()
        { 
            var gen = new WsdlGen(
                @"..\..\..\..\Examples\DocumentRepositoryExample\DocumentRepository.Dto.Xtee\DocumentRepository.Dto.Xtee",
                @"..\..\..\..\Examples\DocumentRepositoryExample\DocumentRepository.Dto\DocumentRepository.Dto",
                @"..\..\..\..\Examples\DocumentRepositoryExample\DocumentRepository.wsdl","Doc", new ServiceInfo("SERVICE","EE","GOV", "700030", "doc"));
            CanGenerateCode(gen, "Doc.Xroad.Eu"); 
        }

        [Test]
        public void CanGenerateCalculatorCode()
        {
            var gen = new WsdlGen(
              @"..\..\..\..\Examples\Calculator\Xtee.Types.Calc.Serialization",
              @"..\..\..\..\Examples\Calculator\Xtee.Types.Calc",
              @"..\..\..\..\Examples\Calculator\Calculator.wsdl", "Calculator", new ServiceInfo("SERVICE", "EE", "GOV", "700030", "Calc"));
            CanGenerateCode(gen, "Calculator.Xroad.Eu"); 
        }
        
        [Test]
        public void CanGeneratePaintShopCode()
        {
            var root = @"..\..\..\..\Examples\PaintShop";
            var gen = new WsdlGen(
              Path.Combine(root, "Xtee.PaintShop"),
              Path.Combine(root, "Xtee.PaintShop"),
              Path.Combine(root, "colors.wsdl"),"Colors", new ServiceInfo("SERVICE", "EE", "GOV", "700030", "Colors"));
            CanGenerateCode(gen, "Colors.Xroad.Eu");
           
        }

        [Test]
        public void CanGenerateXroadMetaAndIdentifiersCode()
        {
            var root = @"..\..\..\Xtee.Core";
            var gen = new WsdlGen(root,
              root,
              Path.Combine(Path.Combine(root,"Wsdl"), "ListAndAllowMethods.wsdl"), "Metadata", new ServiceInfo(), true);
            CanGenerateCode(gen, "Metadata.Xroad.Eu");

        }

        private void CanGenerateCode(WsdlGen gen,string namespaceFolder)
        {
            var modelRoot = new DirectoryInfo(Path.Combine(gen.ModelRootPath, namespaceFolder));
            var serializersRoot = new DirectoryInfo(Path.Combine(gen.ImplementationRootPath, namespaceFolder));

            var files = GetFiles(modelRoot);
            var contents = GetContents(files);
            var fileCountBefore = files.Length;
            var dirCountBefore = GetDirectories(modelRoot).Length;
            var filesOfSerializers = GetFiles(serializersRoot);
            var contentsOfSerializers = GetContents(filesOfSerializers);
            var fileCountOfSerialisersBefore = filesOfSerializers.Length;
            var dirCountOfSerialisersBefore = GetDirectories(serializersRoot).Length;

            gen.Generate();

            AssertFileAndDirecoryCountSame(modelRoot.FullName, dirCountBefore, fileCountBefore);
            AssertFileAndDirecoryCountSame(serializersRoot.FullName, dirCountOfSerialisersBefore, fileCountOfSerialisersBefore);
            AssertFilesAreModified(modelRoot, start);
            AssertFilesAreModified(serializersRoot, start);
            AssertFilesArSame(modelRoot, contents);
            AssertFilesArSame(serializersRoot, contentsOfSerializers);
        }

        private void AssertFilesArSame(DirectoryInfo root, Dictionary<string, string> contents)
        {
            var currentContents = GetContents(GetFiles(root));
            foreach (var key in contents.Keys)
            {
                Assert.That(currentContents[key],Is.EqualTo(contents[key]));  
            } 
        }

        private Dictionary<string,string> GetContents(IEnumerable<FileInfo> files)
        {
            var dic = new Dictionary<string, string>();
            foreach (var fileInfo in files)
            {
                dic.Add(fileInfo.FullName, File.ReadAllText(fileInfo.FullName)); 
            }
            return dic;
        }

        private void AssertFilesAreModified(DirectoryInfo modelRoot, DateTime start)
        {
            foreach (var fileInfo in GetFiles(modelRoot))
            {
                Assert.That(fileInfo.LastWriteTime, Is.GreaterThan(start),
                            string.Format("File {0} was not modified.", fileInfo.FullName));
            }
        }

        private void AssertFileAndDirecoryCountSame(string modelRoot, int dirCountBefore, int fileCountBefore)
        {
            var root = new DirectoryInfo(modelRoot);
            Assert.That(GetDirectories(root).Length, Is.EqualTo(dirCountBefore), "Directory count differss." + root.FullName);
            Assert.That(GetFiles(root).Length, Is.EqualTo(fileCountBefore), "File ile count differs. " + root.FullName);
        }

        private FileInfo[] GetFiles(DirectoryInfo root)
        {
            return root.GetFiles("*", SearchOption.AllDirectories);
        }
        private DirectoryInfo[] GetDirectories(DirectoryInfo root)
        {
            return root.GetDirectories("*", SearchOption.AllDirectories);
        }
       
       
    }

  

    
}
